﻿using System.Collections.Generic;
using System.Linq;

namespace DynamicGeometry
{
    public static class IFigureListExtensions
    {
        public static IEnumerable<IFigure> GetAllFiguresRecursive(
            this IFigure rootFigure)
        {
            IFigureList list = rootFigure as IFigureList;
            if (list != null)
            {
                foreach (var item in list)
                {
                    foreach (var recursive in item.GetAllFiguresRecursive())
                    {
                        yield return recursive;
                    }
                }
            }
            else
            {
                yield return rootFigure;
            }
        }

        public static ILine FindLine(this IEnumerable<IFigure> figures, IPoint p1, IPoint p2)
        {
            foreach (var figure in figures)
            {
                if (figure is ILine
                    && figure.Dependencies.Contains(p1)
                    && figure.Dependencies.Contains(p2))
                {
                    return figure as ILine;
                }
            }
            return null;
        }

        public static IFigure FindFigureWithTheseDependencies<TFigure>(
            this IEnumerable<IFigure> figures,
            params IFigure[] dependencies) where TFigure : IFigure
        {
            foreach (var figure in figures)
            {
                if (figure is TFigure && figure.Dependencies.Match(dependencies))
                {
                    return figure;
                }
            }
            return null;
        }

        public static IFigure FindFigureWithTheseDependenciesInSameOrder<TFigure>(
            this IEnumerable<IFigure> figures,
            params IFigure[] dependencies) where TFigure : IFigure
        {
            foreach (var figure in figures)
            {
                if (figure is TFigure && figure.Dependencies.MatchInSameOrder(dependencies))
                {
                    return figure;
                }
            }
            return null;
        }

        public static bool Match(
            this IEnumerable<IFigure> figures,
            params IFigure[] givenFigures)
        {
            if (figures.Count() != givenFigures.Length)
            {
                return false;
            }
            foreach (var given in givenFigures)
            {
                if (!figures.Contains(given))
                {
                    return false;
                }
            }
            return true;
        }

        public static bool MatchInSameOrder(
            this IEnumerable<IFigure> figures,
            params IFigure[] givenFigures)
        {
            if (figures.Count() != givenFigures.Length)
            {
                return false;
            }
            int i = 0;
            foreach (var given in givenFigures)
            {
                if (given != givenFigures[i++])
                {
                    return false;
                }
            }
            return true;
        }

        public static bool Exists(this IEnumerable<IFigure> figures)
        {
            return figures.All(f => f.Exists);
        }
    }
}
